package dxunderground.utilities.ocr;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import dxunderground.utilities.sql.DataType;
import dxunderground.utilities.sql.RowMapper;
import dxunderground.utilities.sql.Sql;
import dxunderground.utilities.sql.Sql.Type;
import dxunderground.utilities.sql.sqlite.SqliteType;

public class CaptchaDaoImpl implements CaptchaDao {
	private Sql sql;
	private List<Color> ignoredColours;

	public CaptchaDaoImpl(KnownCaptchas knownChaptas, Type type) throws ClassNotFoundException {
		ignoredColours = knownChaptas.getIgnoredColours();
		sql = new Sql(type, "OCR");
	}

	private class CaptchaRowMapper implements RowMapper {

		@Override
		public Object mapRow(ResultSet rs) throws SQLException {
			return new CaptchaImage(rs.getString("captcha"));
		}
	}

	@Override
	public CaptchaImage parseImage(final BufferedImage bufferedImage) {
		return BufferedImageUtility.BinarizateToSampleImage(bufferedImage, ignoredColours);
	}

	@Override
	public List<CaptchaImage> splitImage(final CaptchaImage sampleImage) {
		List<CaptchaImage> chars = splitTrainingImage(sampleImage);

		for (CaptchaImage oneChar : chars)
			oneChar = BufferedImageUtility.trimImage(oneChar);

		return chars;
	}

	@Override
	public void saveImage(CaptchaImage sampleImage) {
		sql.insert("filedropper", new String[] { "captcha" }, new Object[] { sampleImage }, new DataType[] { SqliteType.TEXT });
	}

	@Override
	public List<CaptchaImage> getImages() throws SQLException {
		List<Object> listTemp = sql.select(new CaptchaRowMapper(), "filedropper");
		List<CaptchaImage> list = new ArrayList<CaptchaImage>(listTemp.size());
		for (Object obj : listTemp)
			list.add((CaptchaImage) obj);

		return list;
	}

	private List<CaptchaImage> splitTrainingImage(CaptchaImage sampleImage) {
		// TODO this just looks ugly
		List<CaptchaImage> chars = new ArrayList<CaptchaImage>();

		int startOfChar = 0;
		for (int fromLeft = 0; fromLeft < sampleImage.getWidth(); fromLeft++) {
			for (int i = 0; i < sampleImage.getHeight(); i++) {
				if (sampleImage.getValue()[i][fromLeft] != 0 && fromLeft != sampleImage.getWidth() - 1) {
					break;
				} else if (i == sampleImage.getHeight() - 1) {
					if (fromLeft - startOfChar != 1) {
						Byte[][] values = new Byte[sampleImage.getHeight()][fromLeft - startOfChar];

						for (int j = 0; j < values.length; j++) {
							for (int k = 0; k < values[j].length; k++) {
								values[j][k] = sampleImage.getValue()[j][k + startOfChar];
							}
						}
						chars.add(new CaptchaImage(values));
					}
					startOfChar = fromLeft;
				}
			}
		}
		return chars;
	}
}